{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 输入和输出\n",
    "\n",
    "\n",
    "\n",
    "## numpy 二进制文件\n",
    "\n",
    "`save()`、`savez()`和`load()`函数以 numpy 专用的二进制类型（npy、npz）保存和读取数据，这三个函数会自动处理ndim、dtype、shape等信息，使用它们读写数组非常方便，但是`save()`输出的文件很难与其它语言编写的程序兼容。\n",
    "\n",
    "npy格式：以二进制的方式存储文件，在二进制文件第一行以文本形式保存了数据的元信息（ndim，dtype，shape等），可以用二进制工具查看内容。\n",
    "\n",
    "npz格式：以压缩打包的方式存储文件，可以用压缩软件解压。\n",
    "\n",
    "\n",
    "- `numpy.save(file, arr, allow_pickle=True, fix_imports=True)` Save an array to a binary file in NumPy `.npy` format.\n",
    "- `numpy.load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding='ASCII')` Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\test.npy'\n",
    "np.random.seed(20200619)\n",
    "x = np.random.uniform(0, 1, [3, 5])\n",
    "np.save(outfile, x)\n",
    "y = np.load(outfile)\n",
    "print(y)\n",
    "# [[0.01123594 0.66790705 0.50212171 0.7230908  0.61668256]\n",
    "#  [0.00668332 0.1234096  0.96092409 0.67925305 0.38596837]\n",
    "#  [0.72342998 0.26258324 0.24318845 0.98795012 0.77370715]]\n",
    "```\n",
    "\n",
    "- `numpy.savez(file, *args, **kwds)` Save several arrays into a single file in uncompressed `.npz` format.\n",
    "\n",
    "`savez()`第一个参数是文件名，其后的参数都是需要保存的数组，也可以使用关键字参数为数组起一个名字，非关键字参数传递的数组会自动起名为`arr_0, arr_1, …`。\n",
    "\n",
    "`savez()`输出的是一个压缩文件（扩展名为npz），其中每个文件都是一个`save()`保存的npy文件，文件名对应于数组名。`load()`自动识别npz文件，并且返回一个类似于字典的对象，可以通过数组名作为关键字获取数组的内容。\n",
    "\n",
    "【例】将多个数组保存到一个文件，可以使用`numpy.savez()`函数。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\test.npz'\n",
    "x = np.linspace(0, np.pi, 5)\n",
    "y = np.sin(x)\n",
    "z = np.cos(x)\n",
    "np.savez(outfile, x, y, z_d=z)\n",
    "data = np.load(outfile)\n",
    "np.set_printoptions(suppress=True)\n",
    "print(data.files)  \n",
    "# ['z_d', 'arr_0', 'arr_1']\n",
    "\n",
    "print(data['arr_0'])\n",
    "# [0.         0.78539816 1.57079633 2.35619449 3.14159265]\n",
    "\n",
    "print(data['arr_1'])\n",
    "# [0.         0.70710678 1.         0.70710678 0.        ]\n",
    "\n",
    "print(data['z_d'])\n",
    "# [ 1.          0.70710678  0.         -0.70710678 -1.        ]\n",
    "```\n",
    "\n",
    "用解压软件打开 test.npz 文件，会发现其中有三个文件：`arr_0.npy,arr_1.npy,z_d.npy`，其中分别保存着数组`x,y,z`的内容。\n",
    "\n",
    "\n",
    "---\n",
    "## 文本文件\n",
    "`savetxt()`，`loadtxt()`和`genfromtxt()`函数用来存储和读取文本文件（如TXT，CSV等）。`genfromtxt()`比`loadtxt()`更加强大，可对缺失数据进行处理。\n",
    "\n",
    "- `numpy.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\\n', header='', footer='', comments='# ', encoding=None)` Save an array to a text file.\n",
    "    - fname：文件路径\n",
    "    - X：存入文件的数组。\n",
    "    - fmt：写入文件中每个元素的字符串格式，默认'%.18e'（保留18位小数的浮点数形式）。\n",
    "    - delimiter：分割字符串，默认以空格分隔。\n",
    "\n",
    "\n",
    "- `numpy.loadtxt(fname, dtype=float, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None)` Load data from a text file. \n",
    "    - fname：文件路径。\n",
    "    - dtype：数据类型，默认为float。\n",
    "    - comments: 字符串或字符串组成的列表，默认为# ， 表示注释字符集开始的标志。\n",
    "    - skiprows：跳过多少行，一般跳过第一行表头。\n",
    "    - usecols：元组（元组内数据为列的数值索引）， 用来指定要读取数据的列（第一列为0）。\n",
    "    - unpack：当加载多列数据时是否需要将数据列进行解耦赋值给不同的变量。\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "【例】写入和读出TXT文件。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\test.txt'\n",
    "x = np.arange(0, 10).reshape(2, -1)\n",
    "np.savetxt(outfile, x)\n",
    "y = np.loadtxt(outfile)\n",
    "print(y)\n",
    "# [[0. 1. 2. 3. 4.]\n",
    "#  [5. 6. 7. 8. 9.]]\n",
    "```\n",
    "\n",
    "test.txt文件如下：\n",
    "\n",
    "```python\n",
    "0.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 4.000000000000000000e+00\n",
    "5.000000000000000000e+00 6.000000000000000000e+00 7.000000000000000000e+00 8.000000000000000000e+00 9.000000000000000000e+00\n",
    "```\n",
    "\n",
    "\n",
    "【例】写入和读出CSV文件。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\test.csv'\n",
    "x = np.arange(0, 10, 0.5).reshape(4, -1)\n",
    "np.savetxt(outfile, x, fmt='%.3f', delimiter=',')\n",
    "y = np.loadtxt(outfile, delimiter=',')\n",
    "print(y)\n",
    "# [[0.  0.5 1.  1.5 2. ]\n",
    "#  [2.5 3.  3.5 4.  4.5]\n",
    "#  [5.  5.5 6.  6.5 7. ]\n",
    "#  [7.5 8.  8.5 9.  9.5]]\n",
    "```\n",
    "\n",
    "test.csv文件如下：\n",
    "```python\n",
    "0.000,0.500,1.000,1.500,2.000\n",
    "2.500,3.000,3.500,4.000,4.500\n",
    "5.000,5.500,6.000,6.500,7.000\n",
    "7.500,8.000,8.500,9.000,9.500\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "`genfromtxt()`是面向结构数组和缺失数据处理的。\n",
    "\n",
    "- `numpy.genfromtxt(fname, dtype=float, comments='#', delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars=''.join(sorted(NameValidator.defaultdeletechars)), replace_space='_', autostrip=False, case_sensitive=True, defaultfmt=\"f%i\", unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None, encoding='bytes')` Load data from a text file, with missing values handled as specified.\n",
    "    - names：设置为True时，程序将把第一行作为列名称。\n",
    "\n",
    "\n",
    "data.csv文件如下：\n",
    "```python\n",
    "id,value1,value2,value3\n",
    "1,123,1.4,23\n",
    "2,110,0.5,18\n",
    "3,164,2.1,19\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\data.csv'\n",
    "x = np.loadtxt(outfile, delimiter=',', skiprows=1)\n",
    "print(x)\n",
    "# [[  1.  123.    1.4  23. ]\n",
    "#  [  2.  110.    0.5  18. ]\n",
    "#  [  3.  164.    2.1  19. ]]\n",
    "\n",
    "x = np.loadtxt(outfile, delimiter=',', skiprows=1, usecols=(1, 2))\n",
    "print(x)\n",
    "# [[123.    1.4]\n",
    "#  [110.    0.5]\n",
    "#  [164.    2.1]]\n",
    "\n",
    "val1, val2 = np.loadtxt(outfile, delimiter=',', skiprows=1, usecols=(1, 2), unpack=True)\n",
    "print(val1)  # [123. 110. 164.]\n",
    "print(val2)  # [1.4 0.5 2.1]\n",
    "```\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\data.csv'\n",
    "x = np.genfromtxt(outfile, delimiter=',', names=True)\n",
    "print(x)\n",
    "# [(1., 123., 1.4, 23.) (2., 110., 0.5, 18.) (3., 164., 2.1, 19.)]\n",
    "\n",
    "print(type(x))  \n",
    "# <class 'numpy.ndarray'>\n",
    "\n",
    "print(x.dtype)\n",
    "# [('id', '<f8'), ('value1', '<f8'), ('value2', '<f8'), ('value3', '<f8')]\n",
    "\n",
    "print(x['id'])  # [1. 2. 3.]\n",
    "print(x['value1'])  # [123. 110. 164.]\n",
    "print(x['value2'])  # [1.4 0.5 2.1]\n",
    "print(x['value3'])  # [23. 18. 19.]\n",
    "```\n",
    "\n",
    "data1.csv文件\n",
    "```python\n",
    "id,value1,value2,value3\n",
    "1,123,1.4,23\n",
    "2,110,,18\n",
    "3,,2.1,19\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "outfile = r'.\\data1.csv'\n",
    "x = np.genfromtxt(outfile, delimiter=',', names=True)\n",
    "print(x)\n",
    "# [(1., 123., 1.4, 23.) (2., 110., nan, 18.) (3.,  nan, 2.1, 19.)]\n",
    "\n",
    "print(type(x))  \n",
    "# <class 'numpy.ndarray'>\n",
    "\n",
    "print(x.dtype)\n",
    "# [('id', '<f8'), ('value1', '<f8'), ('value2', '<f8'), ('value3', '<f8')]\n",
    "\n",
    "print(x['id'])  # [1. 2. 3.]\n",
    "print(x['value1'])  # [123. 110.  nan]\n",
    "print(x['value2'])  # [1.4 nan 2.1]\n",
    "print(x['value3'])  # [23. 18. 19.]\n",
    "```\n",
    "\n",
    "---\n",
    "## 文本格式选项\n",
    "\n",
    "- `numpy.set_printoptions(precision=None,threshold=None, edgeitems=None,linewidth=None, suppress=None, nanstr=None, infstr=None,formatter=None, sign=None, floatmode=None, **kwarg)` Set printing options.\n",
    "    - `precision`：设置浮点精度，控制输出的小数点个数，默认是8。\n",
    "    - `threshold`：概略显示，超过该值则以“…”的形式来表示，默认是1000。\n",
    "    - `linewidth`：用于确定每行多少字符数后插入换行符，默认为75。\n",
    "    - `suppress`：当`suppress=True`，表示小数不需要以科学计数法的形式输出，默认是False。\n",
    "    - `nanstr`：浮点非数字的字符串表示形式，默认`nan`。\n",
    "    - `infstr`：浮点无穷大的字符串表示形式，默认`inf`。\n",
    "\n",
    "These options determine the way floating point numbers, arrays and other NumPy objects are displayed.\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.set_printoptions(precision=4)\n",
    "x = np.array([1.123456789])\n",
    "print(x)  # [1.1235]\n",
    "\n",
    "np.set_printoptions(threshold=20)\n",
    "x = np.arange(50)\n",
    "print(x)  # [ 0  1  2 ... 47 48 49]\n",
    "\n",
    "np.set_printoptions(threshold=np.iinfo(np.int).max)\n",
    "print(x)\n",
    "# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23\n",
    "#  24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47\n",
    "#  48 49]\n",
    "\n",
    "eps = np.finfo(float).eps\n",
    "x = np.arange(4.)\n",
    "x = x ** 2 - (x + eps) ** 2\n",
    "print(x)  \n",
    "# [-4.9304e-32 -4.4409e-16  0.0000e+00  0.0000e+00]\n",
    "np.set_printoptions(suppress=True)\n",
    "print(x)  # [-0. -0.  0.  0.]\n",
    "\n",
    "x = np.linspace(0, 10, 10)\n",
    "print(x)\n",
    "# [ 0.      1.1111  2.2222  3.3333  4.4444  5.5556  6.6667  7.7778  8.8889\n",
    "#  10.    ]\n",
    "np.set_printoptions(precision=2, suppress=True, threshold=5)\n",
    "print(x)  # [ 0.    1.11  2.22 ...  7.78  8.89 10.  ]\n",
    "```\n",
    "\n",
    "- `numpy.get_printoptions()` Return the current print options.\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.get_printoptions()\n",
    "print(x)\n",
    "# {\n",
    "# 'edgeitems': 3, \n",
    "# 'threshold': 1000, \n",
    "# 'floatmode': 'maxprec', \n",
    "# 'precision': 8, \n",
    "# 'suppress': False, \n",
    "# 'linewidth': 75, \n",
    "# 'nanstr': 'nan', \n",
    "# 'infstr': 'inf', \n",
    "# 'sign': '-', \n",
    "# 'formatter': None, \n",
    "# 'legacy': False\n",
    "# }\n",
    "```\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python35",
   "language": "python",
   "name": "python35"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
